package gang.org.springframework.framework.metadata;

import gang.org.springframework.framework.core.annotation.GangAnnotationFilter;
import gang.org.springframework.framework.core.annotation.GangMissingMergedAnnotation;

import java.lang.annotation.Annotation;
import java.lang.reflect.AnnotatedElement;
import java.util.Collection;
import java.util.function.Predicate;
import java.util.stream.Stream;

public interface GangMergedAnnotations extends Iterable<GangMergedAnnotation<Annotation>>
{

    /**
     * @param element {@link gang.org.springframework.boot.autoconfigure.GEnableAutoConfiguration}
     *
     * */
    static GangMergedAnnotations from(AnnotatedElement element, SearchStrategy searchStrategy,GangRepeatableContainers repeatableContainers)
    {
        return from(element,searchStrategy,repeatableContainers, GangAnnotationFilter.PLAIN);
    }

    /**
     * @param element {@link gang.org.springframework.boot.autoconfigure.GEnableAutoConfiguration}
     * */
    static GangMergedAnnotations from(AnnotatedElement element, SearchStrategy searchStrategy, GangRepeatableContainers repeatableContainers,GangAnnotationFilter annotationFilter)
    {
        return GangTypeMappedAnnotations.from(element,searchStrategy,repeatableContainers,annotationFilter);
    }

    /**
     * 1,<A extends Annotation> 对返回值的限定，任意继承自Annotation的对象
     * 2,Predicate<? super GangMergedAnnotation<A>> predicate 参数的限定，
     * 3,extends 通配符上限
     * 4,super 通配符下限
     * */
    <A extends Annotation> GangMergedAnnotation get(String annotationType, Predicate<? super GangMergedAnnotation<A>> predicate, GangMergedAnnotationSelector<A> selector);


    enum SearchStrategy
    {
        DIRECT,

        INHERITED_ANNOTATIONS,

        SUPERCLASS,

        TYPE_HIERARCHY,

        TYPE_HIERARCHY_AND_ENCLOSING_CLASSES
    }

    /**
     * 业务意义
     * @param annotations 注解集合，E.g：gang.org.springframework.framework.annotation.GConfiguration
     * */
    static GangMergedAnnotations of(Collection<GangMergedAnnotation<?>> annotations){
        return GangMergedAnnotationsCollection.of(annotations);
    }

    /**
     * 业务意义
     * 用于判断指定的类中，是否使用了指定的注解类
     * E.g 判断工厂类GangWebMvcAutoConfiguration类中，是否使用了GConfiguration注解类
     * */
    boolean isPresent(String annotationType);


    Stream<GangMergedAnnotation<Annotation>> stream();
}
